home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NOVA - For the NeXT Workstation
/
NOVA - For the NeXT Workstation.iso
/
SourceCode
/
AdobeExamples
/
NX_ImportAdv
/
epsfwriter.m
< prev
next >
Wrap
Text File
|
1992-12-19
|
10KB
|
442 lines
/*
* (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved.
*
* (b) If this Sample Code is distributed as part of the Display PostScript
* System Software Development Kit from Adobe Systems Incorporated,
* then this copy is designated as Development Software and its use is
* subject to the terms of the License Agreement attached to such Kit.
*
* (c) If this Sample Code is distributed independently, then the following
* terms apply:
*
* (d) This file may be freely copied and redistributed as long as:
* 1) Parts (a), (d), (e) and (f) continue to be included in the file,
* 2) If the file has been modified in any way, a notice of such
* modification is conspicuously indicated.
*
* (e) PostScript, Display PostScript, and Adobe are registered trademarks of
* Adobe Systems Incorporated.
*
* (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
* CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
* AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
* ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
* OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
* WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
* WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
* DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
* OF THIRD PARTY RIGHTS.
*/
/*
* epsfwriter.c
*
* Version: 2.0
* Author: Ken Fromm
* History:
* 03-07-91 Added this comment.
*/
#import <appkit/NXBitmapImageRep.h>
#import <appkit/color.h>
#import <appkit/graphics.h>
#import <appkit/nextstd.h>
#import <appkit/tiff.h>
#import <dpsclient/dpsclient.h>
#import <dpsclient/wraps.h>
#import <objc/List.h>
#import <objc/hashtable.h>
#import <streams/streamsimpl.h>
#import <streams/streams.h>
#import "ImportApp.h"
#import "epsfstruct.h"
#import "epsfwraps.h"
#define MAX_CHARS 255
#define MAX_BYTES 127
extern void GetDocumentComment();
extern NXColor GetColorAt(NXBitmapImageRep *image, int x, int y);
extern void LogEpsfError();
/*
* These arrays contain the proper instructions for including, initiating
* and terminating procedure sets using the Adobe Illustrator format.
*/
const static char EpsfProcSetDef[ ] =
"% EPSF_Illustrator_abbrev
% Version 1.0 8/23/1990
% Copyright (C) 1987, 1988, 1989, 1990
% Adobe Systems Incorporated
% All Rights Reserved
userdict /EPSF_Illustrator_abbrev 14 dict dup begin put
% initialization
/initialize % - initialize -
{
userdict /EPSF_Illustrator_abbrev_vars 1 dict dup begin put
/_i null def
EPSF_Illustrator_abbrev begin
EPSF_Illustrator_abbrev
{
dup xcheck
{
bind
} if
pop pop
} forall
end
end
EPSF_Illustrator_abbrev begin
EPSF_Illustrator_abbrev_vars begin
newpath
} def
/terminate % - terminate -
{
end
end
} def
/ddef % key value ddef -
{
EPSF_Illustrator_abbrev_vars 3 1 roll put
} def
/npop % integer npop -
{
{
pop
} repeat
} def
% color operators
/g % gray g -
{
setgray
} def
% graphic state operators
/d % array phase d -
{
setdash
} def
/cf % - cf flatness
currentflat def
/i % flatness i -
{
dup 0 eq
{
pop cf
} if
setflat
} def
/j % linejoin j -
{
setlinejoin
} def
/J % linecap J -
{
setlinecap
} def
/M % miterlimit M -
{
setmiterlimit
} def
/w % linewidth w -
{
setlinewidth
} def
% place operators
/` % matrix llx lly urx ury string ` -
{
/_i save ddef
pop 5 -1 roll concat
newpath 4 2 roll 2 copy moveto
3 1 roll 1 index lineto
2 index exch lineto
lineto
closepath
clip newpath
userdict begin
/showpage {} def
} def
/~ % - ~ -
{
end
_i restore
} def
currentdict readonly pop end\n";
const static char EpsfProcSetInit[ ] = "EPSF_Illustrator_abbrev /initialize get exec\n";
const static char EpsfProcSetTerm[ ] = "EPSF_Illustrator_abbrev /terminate get exec\n";
void WriteEpsfProcSetDef ()
{
DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetDef, strlen(EpsfProcSetDef));
}
void WriteEpsfProcSetInit ()
{
DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetInit, strlen(EpsfProcSetInit));
}
void WriteEpsfProcSetTerm ()
{
DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetTerm, strlen(EpsfProcSetTerm));
}
/*
* Writes the Adobe Illustrator 88 imported document operator.
*/
void WriteEpsfIllustratorBeg(NXRect *bounds, NXRect *boundsOrig, float rotation, char *filename)
{
float a = 1.0, b = 0.0,
c = 0.0, d = 1.0,
sx = 1.0, sy = 1.0;
NXPoint t;
DPSContext ctxt;
if (boundsOrig->size.width)
sx = bounds->size.width/boundsOrig->size.width;
if (boundsOrig->size.height)
sy = bounds->size.height/boundsOrig->size.height;
if (rotation != 0.0)
{
a = d = (float) cos(rotation);
b = c = (float) sin(rotation);
c = -c;
}
a = a * sx;
b = b * sx;
c = c * sy;
d = d * sy;
t.x = bounds->origin.x - boundsOrig->origin.x * sx;
t.y = bounds->origin.y - boundsOrig->origin.y * sy;
ctxt = DPSGetCurrentContext();
DPSPrintf(ctxt, "\n0 g 0 i 0 J 0 j 1 w 10 M [] 0 d\n");
DPSPrintf(ctxt, "[%g %g %g %g %g %g] %g %g %g %g", a, b, c, d, t.x, t.y,
boundsOrig->origin.x, boundsOrig->origin.y,
boundsOrig->origin.x + boundsOrig->size.width,
boundsOrig->origin.y + boundsOrig->size.height);
if (filename)
DPSPrintf(ctxt, " (%s)", filename);
else
DPSPrintf(ctxt, " ( )");
DPSPrintf(ctxt, " `\n");
DPSPrintf(ctxt, "%%%%BeginDocument: ");
if (filename)
DPSPrintf(ctxt, "%s", filename);
DPSPrintf(ctxt,"\n");
}
void WriteEpsfIllustratorInclude(char *name)
{
DPSContext ctxt;
ctxt = DPSGetCurrentContext();
DPSPrintf(ctxt, "%%%%IncludeFile: ");
if (name)
DPSPrintf(ctxt, "%s", name);
DPSPrintf(ctxt, "\n");
}
void WriteEpsfIllustratorEnd()
{
DPSContext ctxt;
ctxt = DPSGetCurrentContext();
DPSPrintf(ctxt, "%%%%EndDocument\n");
DPSPrintf(ctxt, "~\n\n");
}
void WriteEpsfResource(id list, int i, int j)
{
int k, count,
linelen, datalen, commentlen;
char comment[EPSF_MAXCOMMENTSUB];
NXAtom data;
DPSContext ctxt;
count = [list count];
if (count)
{
ctxt = DPSGetCurrentContext();
GetDocumentComment(comment, i, j);
DPSPrintf(ctxt, comment);
linelen = commentlen = strlen(comment);
for (k = 0; k < count; k++)
{
data = (NXAtom) [list objectAt:k];
datalen = strlen(data);
if (datalen + linelen > EPSF_MAXCOMMENT)
{
/* Prevents an infinite loop for a single large datalen. */
if (commentlen != linelen)
{
DPSPrintf(ctxt, "\n%%%%+");
linelen = commentlen = 3;
}
}
DPSPrintf(ctxt, " %s", data);
linelen += datalen;
}
DPSPrintf(ctxt, "\n");
}
}
static char GetBlackWhiteAt(NXBitmapImageRep *image, int x, int y)
{
int bps, spp, amask;
unsigned char gray;
spp = [image samplesPerPixel];
bps = [image bitsPerSample];
amask = (1 << bps) - 1; // 1, 3, 15, 255 for bps = 1, 2, 4, 8
if ([image isPlanar])
{
int pixel = x * bps;
int byteLoc = [image bytesPerRow] * y + (pixel >> 3);
int bitLoc = pixel & 7;
gray = ((*([image data]+byteLoc)) >> (8 - bitLoc - bps)) & amask;
}
else
{
unsigned char *byteLoc = [image data] + [image bytesPerRow] * y;
int bitLoc = x * bps * spp;
gray = ((byteLoc[bitLoc >> 3]) >> (8 - (bitLoc & 7) - bps)) & amask;
}
return (gray >> 1 ? 0 : 1);
}
void WriteEpsfPreview(id image)
{
int byte, orbyte;
int i, j, width, height,
pos, bytes;
DPSContext ctxt;
if (image)
{
ctxt = DPSGetCurrentContext();
width = [image pixelsWide];
height = [image pixelsHigh];
DPSPrintf(ctxt, "%%%%BeginPreview: %d %d %d %d",
width, height, 1, (((width-1)/8)/MAX_BYTES + 1) *height);
for (i = 0; i < height; i++)
{
DPSPrintf(ctxt, "\n%% ");
pos = 7;
byte = 0;
bytes = 0;
for (j = 0; j < width; j++, pos--)
{
orbyte = GetBlackWhiteAt(image, j, i) << pos;
byte = byte | orbyte;
if (pos == 0 || j == width - 1)
{
bytes++;
if (bytes > MAX_BYTES)
{
bytes = 0;
DPSPrintf(ctxt, "\n%% ");
}
DPSPrintf(ctxt, "%02x", byte);
pos = 8;
byte = 0;
}
}
}
DPSPrintf(ctxt, "\n%%%%EndPreview\n\n");
}
}
/*
* This does nothing in the way of error recovery. It is used to demonstrate the
* problems on not using a separate context. Eps files with errors can potentially
* harm the application's context. The recommended approach is to use
* the NXEPSImageRep object to image the file.
*/
int WriteEpsf(const char *name, NXRect *bounds, NXRect *boundsOrig)
{
BOOL trace;
int error, len, maxlen;
char *data;
NXStream *stream;
DPSContext ctxt;
trace = [NXApp tracingFlag];
error = EPSF_OK;
stream = NXMapFile(name, NX_READONLY);
if (stream)
{
NXGetMemoryBuffer(stream, &data, &len, &maxlen);
if (data && len)
{
ctxt = DPSGetCurrentContext();
error = EPSF_WRITEERROR;
NX_DURING
DPSTraceContext(ctxt, trace);
PSWBeginEpsf();
PSWSetEpsf(bounds->origin.x, bounds->origin.y, bounds->size.width,
bounds->size.height, boundsOrig->origin.x, boundsOrig->origin.y,
boundsOrig->size.width, boundsOrig->size.height, 0);
DPSPrintf(ctxt, "%%%%BeginDocument: %s\n", name);
DPSPrintf(ctxt, "%%%% ...Included EPS file here... \n");
DPSTraceContext(ctxt, NO);
DPSWritePostScript(ctxt, data, len);
DPSTraceContext(ctxt, trace);
DPSPrintf(ctxt, "%%%%EndDocument\n");
PSWEndEpsf();
DPSTraceContext(ctxt, NO);
DPSFlushContext(ctxt);
error = EPSF_OK;
NX_HANDLER
if (NXLocalHandler.code == dps_err_ps)
LogEpsfError(&NXLocalHandler);
else
NX_RERAISE();
NX_ENDHANDLER
}
}
return error;
}